package com.yonghui.summer.utils;

import com.yonghui.summer.po.MybatisSql;
import com.yonghui.summer.po.ParamValue;
import com.yonghui.summer.po.SqlParams;

import javax.annotation.processing.Messager;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.tools.Diagnostic;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @auther yangchuan
 * @date 2021-03-26 17:22
 */

public class SqlHelper {
    private static Pattern argsPattern = Pattern.compile("\\#\\{(.*?)\\}");
    private static final String staticType = "[Select],[Insert],[Update],[Delete]";
    private static final String dynamicType = "[SelectProvider],[InsertProvider],[UpdateProvider],[DeleteProvider]";
    /**
     * 分析sql处理完成
     * @param sql
     * @param params
     * @return
     */
    public static SqlParams analyseSql(String sql, List<ParamValue> params ){

        String newSql = null;
        Matcher m = argsPattern.matcher(sql);
        List<Object> args = new ArrayList<>();
        String name = null;
        boolean flag = false;
        while(m.find()) {
            name = m.group(1);
            flag = false;
             for(ParamValue pv : params){
                 if(name.equals(pv.getName())){
                     args.add(pv.getValue());
                     flag = true;
                 }
             }
             if(!flag){
                 throw new IllegalArgumentException("没有找到sql中的"+name+"参数");
             }
        }
        newSql = sql.replaceAll(argsPattern.pattern(),"?");
        return new SqlParams(newSql,args);
    }



    public static MybatisSql getMybatisSql(Element element, Messager messager){
        List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors();
        if(annotationMirrors == null){
            messager.printMessage(Diagnostic.Kind.ERROR, "方法没有使用任何mybatis的注解，确认非脱机要使用的sql，请使用@DaoSkip跳过" ,element);
        }
        String sql = null;
        String provider = null;
        String providerMethod = null;
        MybatisSql mybatisSql = new MybatisSql();
        for (AnnotationMirror am : annotationMirrors) {
            String annotationType = "[" + am.getAnnotationType().asElement().getSimpleName().toString() + "]";
            messager.printMessage(Diagnostic.Kind.NOTE, "----annotationType----:" + annotationType);
            if(annotationType.startsWith("[Select")){
                mybatisSql.setAndroidMethod("rawQuery");
            }else{
                mybatisSql.setAndroidMethod("execSQL");
            }
            if (dynamicType.contains(annotationType)) {
                Set<? extends ExecutableElement> keys = am.getElementValues().keySet();
                for (ExecutableElement key : keys) {
                    if (key.getSimpleName().toString().equals("type")) {
                        provider = am.getElementValues().get(key).toString();
                        provider = provider.substring(0, provider.length() - ".class".length());
                    }
                    if (key.getSimpleName().toString().equals("method")) {
                        providerMethod = am.getElementValues().get(key).toString();
                        //方法名称带有双引号
                        providerMethod = providerMethod.substring(1, providerMethod.length() - 1);
                    }
                }
                mybatisSql.setFromType(MybatisSql.FROM_TYPE_DYNAMIC);
                mybatisSql.setSql("(new "+provider + "())." + providerMethod);
                return mybatisSql;
            }
            if (staticType.contains(annotationType)) {
                Set<? extends ExecutableElement> keys = am.getElementValues().keySet();
                for (ExecutableElement key : keys) {
                    if (key.getSimpleName().toString().equals("value")) {
                        messager.printMessage(Diagnostic.Kind.NOTE, "----sql----:" + am.getElementValues().get(key).getValue());
                        sql = am.getElementValues().get(key).getValue().toString();
                        sql = sql.substring(1, sql.length() - 1);
                        mybatisSql.setFromType(MybatisSql.FROM_TYPE_STATIC);
                        mybatisSql.setSql(sql);
                        return mybatisSql;
                    }
                }
            }
        }
        messager.printMessage(Diagnostic.Kind.ERROR, "方法没有使用任何mybatis的注解，确认非脱机要使用的sql，请使用@DaoSkip跳过" ,element);
        return null;
    }

    public static void main(String[] args){
        String sql = "select * from a where name like concat(#{a[0].userName},'%') and b=#{bb}";
        Matcher m = argsPattern.matcher(sql);
        while(m.find()) {
            System.out.println(m.group(1));
        }
        System.out.println(sql.replaceAll(argsPattern.pattern(),"?"));
    }

}
